home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stream.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "explode.h"
- #include <gl/gl.h>
- extern "C" {
- #include "image.h"
- int iclose(IMAGE*);
- int getrow(IMAGE*, unsigned short*, unsigned int, unsigned int);
- }
-
- #define EXPLOSIONFRAMES 30
- #define FADEFRAME 23
- #define FADINGFRAMES (EXPLOSIONFRAMES - FADEFRAME - 1)
-
- static unsigned long* explosions[EXPLOSIONFRAMES][7];
- static unsigned short rbuf[256], gbuf[256], bbuf[256];
-
- //IMAGE *iopen(char *file, char *mode, ...);
- IMAGE *iopen(char *file, char *mode);
-
- static unsigned long* readImage(char* fname, float opacity)
- {
- float intensity;
- IMAGE* image;
- short x, y;
- unsigned long* i, *s;
-
- if ((image = iopen(fname, "r")) == NULL) {
- cerr << "can't open image " << fname << endl;
- return NULL; // can't open image
- }
- if (image->xsize != 64 || image->ysize != 64) { // wrong size
- cerr << "bad image size: " << image->xsize << "x" << image->ysize << "\n";
- return NULL;
- }
- if (image->zsize < 3) { // not an RGB image
- cerr << "not an RGB image\n";
- return NULL;
- }
-
- i = (unsigned long*)malloc(image->xsize*image->ysize*sizeof(unsigned long));
- if (!i) {
- cerr << "can't allocate memory\n";
- return NULL;
- }
- for (s = i, y = 0; y < image->ysize; y++) {
- getrow(image, rbuf, y, 0);
- getrow(image, gbuf, y, 1);
- getrow(image, bbuf, y, 2);
- for (x = 0; x < image->xsize; s++, x++) {
- intensity = float((rbuf[x] > gbuf[x]) ? rbuf[x] : gbuf[x]);
- if (float(bbuf[x]) > intensity) intensity = float(bbuf[x]);
- intensity *= 2.5 * opacity;
- if (intensity > 255.0) intensity = 255.0;
- *s = ((unsigned long)(intensity + 0.5) << 24) |
- ((unsigned long)(bbuf[x] * opacity + 0.5) << 16) |
- ((unsigned long)(gbuf[x] * opacity + 0.5) << 8) |
- (unsigned long)(rbuf[x] * opacity + 0.5);
- }
- }
- iclose(image);
- return i;
- }
-
- unsigned long* shrinkImage(unsigned long* image, int size)
- {
- unsigned long* shrunk = (unsigned long*)malloc((size>>1) * (size>>1) *
- sizeof(unsigned long));
- if (!shrunk) return NULL;
- unsigned long* s1 = image, *s2 = shrunk;
- for (int i = 0; i < size; s1 += size, i += 2)
- for (int j = 0; j < size; s1 += 2, s2++, j += 2) {
- // FIXME -- average four pixels instead of ZOH
- *s2 = *s1;
- }
- return shrunk;
- }
-
- int readExplosion(const char* dir)
- {
- char namebuf[256];
- for (int i = 0; i < EXPLOSIONFRAMES; i++) {
- float opacity = (i < FADEFRAME) ? 1.0 :
- float(EXPLOSIONFRAMES-i-1) / FADINGFRAMES;
- sprintf(namebuf, "%s/e%02d.rgb", dir, i+1);
- if (!(explosions[i][0] = readImage(namebuf, opacity)))
- return FALSE;
- for (int j = 1, s = 64; j < 7; s >>= 1, j++)
- if (!(explosions[i][j] = shrinkImage(explosions[i][j-1], s))) {
- cerr << "couldn't shrink to size " << (s >> 1) << endl;
- return FALSE;
- }
- }
- return TRUE;
- }
-
- static short erv[4][2];
-
- void drawExplosion(short x, short y, short r, float z,
- float t)
- {
- if (r <= 0) return; // too small
-
- short size, sizeIndex, zoom = 1;
- if (r > 32) {
- while (r > 64) { zoom++; r -= 64; }
- sizeIndex = 0;
- }
- else if (r > 16) sizeIndex = 1;
- else if (r > 8) sizeIndex = 2;
- else if (r > 4) sizeIndex = 3;
- else if (r > 2) sizeIndex = 4;
- else if (r > 1) sizeIndex = 5;
- else sizeIndex = 6;
- short isize = 128 >> (sizeIndex + 1);
- size = zoom * isize;
-
- int frame = int((1.0 - t) * (EXPLOSIONFRAMES - 1) + 0.5);
- if (frame >= EXPLOSIONFRAMES) frame = EXPLOSIONFRAMES - 1;
- x -= (size >> 1);
- y -= (size >> 1);
-
- erv[0][0] = x; erv[0][1] = y;
- erv[1][0] = x+size-1; erv[1][1] = y;
- erv[2][0] = x+size-1; erv[2][1] = y+size-1;
- erv[3][0] = x; erv[3][1] = y+size-1;
- wmpack(0);
- stencil(TRUE, 1, SF_ALWAYS, 0x1, ST_KEEP, ST_KEEP, ST_REPLACE);
- pushmatrix();
- translate(0.0, 0.0, -z);
- bgnpolygon();
- v2s(erv[0]);
- v2s(erv[1]);
- v2s(erv[2]);
- v2s(erv[3]);
- endpolygon();
- popmatrix();
- wmpack(0xffffffff);
- stencil(TRUE, 1, SF_EQUAL, 0x1, ST_ZERO, ST_ZERO, ST_ZERO);
- if (zoom != 0) rectzoom(float(zoom), float(zoom));
- lrectwrite(x, y, x + isize - 1, y + isize - 1, explosions[frame][sizeIndex]);
- if (zoom != 0) rectzoom(1.0, 1.0);
- stencil(FALSE, 0, SF_ALWAYS, 0, ST_KEEP, ST_KEEP, ST_KEEP);
- }
-